Render this report with ~/spinal_cord_paper/scripts/Gg_devel_scWGCNA_module_analysis_render.sh.

library(Seurat)
## Attaching SeuratObject
library(WGCNA)
## Loading required package: dynamicTreeCut
## Loading required package: fastcluster
## 
## Attaching package: 'fastcluster'
## The following object is masked from 'package:stats':
## 
##     hclust
## 
## 
## Attaching package: 'WGCNA'
## The following object is masked from 'package:stats':
## 
##     cor
library(tidyr)
library(ggplot2)
library(stringr)
library(patchwork)
library(tidyverse)
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.1 ──
## ✔ tibble  3.1.8      ✔ dplyr   1.0.10
## ✔ readr   1.4.0      ✔ forcats 0.5.1 
## ✔ purrr   0.3.4
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
library(cowplot)
## 
## Attaching package: 'cowplot'
## The following object is masked from 'package:patchwork':
## 
##     align_plots
library(pheatmap)
library(gridExtra)
## 
## Attaching package: 'gridExtra'
## The following object is masked from 'package:dplyr':
## 
##     combine

Load individual seurat and test WGCNA data

The individual data sets are the Day 5 (Gg_D05_ctrl_seurat_070323), Day 7 (Gg_D07_ctrl_seurat_070323), and Day 10 (Gg_ctrl_1_seurat_070323) chicken spinal cord sets. The test WGCNA data are the modules calculated on the integrated data set of all three stages.

se_path <- c("Gg_D05_ctrl_seurat_070323",
             "Gg_D07_ctrl_seurat_070323",
             "Gg_ctrl_1_seurat_070323")

clust_col <- read.csv("~/spinal_cord_paper/annotations/broad_cluster_marker_colors.csv") %>% 
  rename(broad = broad_cluster) %>% 
  select(-marker)

Order of the broad clusters for plotting purposes.

broad_order <- c("progenitors",
      "FP",
      "RP",
      "FP/RP",
      "neurons",
      "OPC",
      "MFOL",
      "pericytes",
      "microglia",
      "blood",
      "vasculature"
      )
my.ses <- list()
col_table <- list()
ord_levels <- list()

for (i in seq(se_path)) {
  # load the data sets
  my.se <- readRDS(paste0("~/spinal_cord_paper/data/", se_path[i], ".rds"))
  annot <- read.csv(list.files("~/spinal_cord_paper/annotations",
                               pattern = str_remove(se_path[i], "_seurat_\\d{6}"),
                               full.names = TRUE))
  
  if(length(table(annot$number)) != length(table(my.se$seurat_clusters))) {
     stop("Number of clusters must be identical!")
  }
  
  # rename for left join
  annot <- annot %>% 
    mutate(fine = paste(fine, number, sep = "_")) %>% 
    mutate(number = factor(number, levels = 1:nrow(annot))) %>% 
    rename(seurat_clusters = number) 
  
  # cluster order for vln plots
  ord_levels[[i]] <- annot$fine[order(match(annot$broad, broad_order))]
  
  # create index for color coding
  col_table[[i]] <- annot %>%
    left_join(clust_col, by = "broad") %>% 
    select(c("fine", "color"))
  
  # add cluster annotation to meta data
  my.se@meta.data <- my.se@meta.data %>% 
    rownames_to_column("rowname") %>% 
    left_join(annot, by = "seurat_clusters") %>% 
    mutate(fine = factor(fine, levels = annot$fine)) %>% 
    column_to_rownames("rowname")
  
  my.ses[[i]] <- my.se

}

names(my.ses) <- c("D05", "D07", "D10")
names(col_table) <- c("D05", "D07", "D10")
names(ord_levels) <- c("D05", "D07", "D10")

rm(my.se, annot)
# The reference WGCNA data. We can have several, if we want to test many at the same time
WGCNA_data = list()
WGCNA_data[[1]] = readRDS("~/spinal_cord_paper/output/Gg_devel_int_scWGCNA_250723.rds")
my.wsub =list()
my.wsub[[1]]= c(1:22)

# the name of each sample, as they appear in my.files and in the metadata of the combined object
my.samplenames = c("D05", "D07", "D10")

# This is just to add a little bit more sense to the modules, so that we don't get just a color. Corresponds to WGCNA_data
my.modulenames = list()
my.modulenames[[1]] = c(1:22)

Module gene correlation

Here, we do a correlation matrix / heatmap, to see which cell clusters group togheter. This helps us to make more detailed dotplots.
This part of the script can still be used to compare several WGCNA datasets in parallel.

# broad cluster color table
all_col <- do.call(rbind, col_table) %>% 
  rownames_to_column("sample") %>% 
  mutate(sample = substr(sample, 1, 3)) %>% 
  mutate(sample_celltype = paste(sample, fine, sep = "_")) %>% 
  select(c("color", "sample_celltype", "sample"))

Meta data

#Get a dataframe with annotations for all the samples and colors we need.
my.metam <- list()

for (i in seq(my.ses)) {
  my.metam[[i]] <- my.ses[[i]][[]]
  rownames(my.metam[[i]]) <- paste0(rownames(my.metam[[i]]), "_", i)
}
my.metam <- do.call(rbind, my.metam)

my.metam$orig.ident <- str_replace_all(my.metam$orig.ident, pattern =  "Gg_D05_ctrl", "D05")
my.metam$orig.ident <- str_replace_all(my.metam$orig.ident, pattern =  "Gg_D07_ctrl", "D07")
my.metam$orig.ident <- str_replace_all(my.metam$orig.ident, pattern =  "Gg_ctrl_1", "D10")

# my.metam$sample_celltype = paste0(substr(my.metam$orig.ident,7,9),"_",my.metam$seurat_clusters)
my.metam$sample_celltype = paste0(my.metam$orig.ident, "_", my.metam$fine)

my.metam <- my.metam %>% 
  tibble::rownames_to_column(var = "cell_ID") %>%
  dplyr::left_join(all_col, by = "sample_celltype") %>%
  tibble::column_to_rownames(var = "cell_ID")


# get sample colors
my.colsm = c("grey", "grey30", "black")
names(my.colsm) <- c("D05", "D07", "D10")

Average expression data

cell_table <- my.metam %>% 
  rownames_to_column("cell_ID") %>% 
  select("sample_celltype", "cell_ID")

avg.mod.eigengenes <- WGCNA_data[[1]]$sc.MEList$averageExpr %>% 
  rownames_to_column("cell_ID") %>% 
  left_join(cell_table, by = "cell_ID") %>% 
  column_to_rownames("cell_ID")
  

# add metadata

avg.mod.eigengenes.mean <- avg.mod.eigengenes %>%
  group_by(sample_celltype) %>%
  summarise_all("mean") %>%
  column_to_rownames("sample_celltype")

spearman correlation heatmap

annotations

# names and colors for the heatmap annotation
annot_name <- data.frame(
  "Celltypes" = all_col$sample_celltype,
  "Sample"    = all_col$sample,
  row.names = all_col$sample_celltype)
  

annot_module <- data.frame(
  "Module" = colnames(avg.mod.eigengenes)[1:22],
  row.names = colnames(avg.mod.eigengenes)[1:22]
)

pheat_col_table <- do.call(rbind, col_table) %>% 
  rownames_to_column("sample") %>% 
  mutate(sample = substr(sample, 1,3)) %>% 
  mutate(fine = paste(sample, fine, sep = "_"))

# match color table with annotation
pheat_col_table <- pheat_col_table[match(annot_name$Celltypes, pheat_col_table$fine),]

annot_col <- list(
  Celltypes = pheat_col_table$color,
  Sample = c(D05 = "#A4A4A4",
             D07 = "#515151",
             D10 = "#000000"),
  Module = str_remove(colnames(avg.mod.eigengenes)[1:22], "AE")
  )

names(annot_col[[1]]) <- annot_name$Celltypes
names(annot_col[[3]]) <- colnames(avg.mod.eigengenes)[1:22]

heatmap of module pseudobulk average expression

# module colors
my.colcols = as.matrix(names(table(WGCNA_data[[1]]$dynamicCols)))

htmp <- pheatmap(as.matrix(avg.mod.eigengenes.mean),
         fontsize = 8,
         scale = "column",
         color = colorRampPalette(c("#4d2d87","#7c55a3", "white", "#ed9921", "#895d25"))(n = 1000),
         annotation_row = annot_name,
         annotation_col = annot_module,
         annotation_colors = annot_col,
         annotation_legend = F,
         border_color = NA)

# clustering from the scaled heatmap
row_order <- htmp[["tree_row"]]
col_order <- htmp[["tree_col"]]


# threshold the values to abs(mat) = 5
mat_scaled <- scale(as.matrix(avg.mod.eigengenes.mean))
mat_scaled[mat_scaled > 5] <- 5
mat_scaled[mat_scaled < -5] <- -5


max5 <- pheatmap(as.matrix(mat_scaled),
                 fontsize = 8,
                 color = colorRampPalette(c("#4d2d87","#7c55a3", "white", "#ed9921", "#895d25"))(n = 1000),
                 cluster_rows = row_order,
                 cluster_cols = col_order,
                 annotation_row = annot_name,
                 annotation_col = annot_module,
                 annotation_colors = annot_col,
                 annotation_legend = F,
                 border_color = NA)

# module order vector (not hclust object as above)
module_order <- htmp[["tree_col"]]$order

pdf("~/spinal_cord_paper/figures/Fig_1_devel_module_v_clusters_heatmap.pdf", width = 8, height = 10)
grid.arrange(max5$gtable)
dev.off()
## png 
##   2

Load the integrated data set

The integrated data set on which the WGCNA is calculated. We plot it, split by the original cell types from the three original samples.

# This is a file of all the combined mouse datasets, normalized and such.
my.sec = readRDS("~/spinal_cord_paper/data/Gg_devel_int_seurat_250723.rds")

identical(rownames(my.metam), colnames(my.sec))
## [1] TRUE
my.metam$sample_celltype <- factor(my.metam$sample_celltype, levels = all_col$sample_celltype)
#Set the identities of the integrated data, to the annotated clusters
my.sec = SetIdent(my.sec, value = my.metam$sample_celltype)

p1 <- DimPlot(
  my.sec,
  reduction = "tsne",
  label = TRUE,
  repel = TRUE,
  cols = all_col$color,
  split.by = "orig.ident"
  ) + 
  NoLegend()

p1

pdf("~/spinal_cord_paper/figures/Devel_split_tsne.pdf", height = 7, width = 15)
#Plot split tsne
p1

Avg. module exp. by stage

tSNE DimPlots showing the average expression of each module by stage.

for (i in seq(my.ses)) {
  # prepare average expression table
  tmp <- avg.mod.eigengenes[,1:22] %>%
    tibble::rownames_to_column("cell_ID") %>%
    dplyr::filter(grepl(paste0("_", i, "$"), cell_ID)) %>%
    dplyr::mutate(cell_ID = stringr::str_remove_all(cell_ID, paste0("_", i))) %>%
    tibble::column_to_rownames("cell_ID")
  
  identical(rownames(tmp), colnames(my.ses[[i]]))
  # add meta data to the seurat objects
  my.ses[[i]] <- AddMetaData(my.ses[[i]], tmp)
}

#max and min expression per module (column max)
mod_max <- apply(avg.mod.eigengenes[,1:22], MARGIN = 2, FUN = max)[module_order]
mod_min <- apply(avg.mod.eigengenes[,1:22], MARGIN = 2, FUN = min)[module_order]

modplots <- list()
modplots[[1]] <- list()
modplots[[2]] <- list()
modplots[[3]] <- list()

modules_in_order <- colnames(tmp)[module_order]

# plot the modules split to the stages
for (i in seq(my.ses)) {
  for (j in seq(ncol(tmp))) {
  
    modplots[[i]][[j]]  <- FeaturePlot(
      my.ses[[i]], order = TRUE,
      features = modules_in_order[j],
      reduction = "tsne"
      ) +
      ggtitle(stringr::str_remove(modules_in_order[j],"^AE")) +
      scale_color_gradient(low="ivory2", high=substring(modules_in_order[j], 3), #colors in the scale
                 limits=c(mod_min[j], mod_max[j])) #same limits for plots

    
    }
}

full_plot <- c(modplots[[1]], modplots[[2]], modplots[[3]])

gridExtra::grid.arrange(grobs = full_plot, ncol = 3, as.table = FALSE)

pdf("~/spinal_cord_paper/figures/Fig_2_devel_modules_AE_plots.pdf", width = 12, height = 70)
gridExtra::grid.arrange(grobs = full_plot, ncol = 3, as.table = FALSE)

pdf("~/spinal_cord_paper/figures/Supp_Fig_2_modules_darkgreen_AE_plots.pdf", width = 13, height = 4)
(full_plot[[9]] + full_plot[[31]] + full_plot[[53]]) + plot_layout(ncol = 3, guides = "collect")

AE over time

We plot the average expression of each module in the three stages and the 5 broad cell type clusters present in all 3 stages.

# module annotations
mod_annot <- read.csv("~/spinal_cord_paper/annotations/Gg_devel_int_scWGCNA_module_annotation.csv") %>%
  dplyr::mutate(module = str_replace_all(module, "\\d{1,2}\\_", "AE"))

meta <- list()

for (i in seq(my.ses)) {
  meta[[i]] <- my.ses[[i]]@meta.data %>%
    tibble::rownames_to_column("cell_ID") %>%
    dplyr::mutate(cell_ID = paste0(cell_ID, "_", i)) %>%
    dplyr::select(c("cell_ID", "broad"))
}

meta <- do.call(rbind, meta)

# mean average expression by stage
mean_AE <- avg.mod.eigengenes[,1:22] %>%
  tibble::rownames_to_column("cell_ID") %>%
  dplyr::mutate(stage = stringr::str_sub(cell_ID, -1)) %>%
  dplyr::mutate(stage = factor(stage, levels = c(1:3), labels = c("D05", "D07", "D10"))) %>%
  dplyr::left_join(meta, by = "cell_ID") %>%
  tibble::column_to_rownames("cell_ID") %>%
  tidyr::unite("stage_cl", stage, broad, sep = "_") %>%
  dplyr::group_by(stage_cl) %>%
  dplyr::summarise_each(mean) %>%
  dplyr::ungroup() %>%
  gather(key="module", value = "AE", -stage_cl) %>%
  dplyr::left_join(mod_annot[, c(1,3)], by = "module") %>%
  tidyr::separate("stage_cl", c("stage", "broad"), sep = "_", remove = FALSE) 
## Warning: `summarise_each_()` was deprecated in dplyr 0.7.0.
## ℹ Please use `across()` instead.
## ℹ The deprecated feature was likely used in the dplyr package.
##   Please report the issue at <https://github.com/tidyverse/dplyr/issues>.
labels_dotplot <- stringr::str_remove(modules_in_order, "^AE")
names(labels_dotplot) <- modules_in_order

plot_clusters <- c("progenitors", "neurons", "RP", "FP", "pericytes", "OPC", "MFOL", "microglia", "blood")

mean_mod <- ggplot(data = mean_AE,
  aes(
    x = stage,
    y = AE,
    color = factor(broad, levels = plot_clusters),
    group = broad,
    label = annotation
    )
  ) +
  geom_line() +
  geom_point() +
  scale_color_manual(values = clust_col$color[match(plot_clusters, clust_col$broad)]) +
  theme_bw() +
  # facet wrap with reordered factors
  facet_wrap(vars(factor(module, levels = unique(mean_AE$module)[module_order])),
             scales = "free_y",
             nrow = 4,
             ncol = 6) +
  labs(color = "broad") +
  ggtitle("Average module expression by stage")

plotly::ggplotly(mean_mod)
pdf("~/spinal_cord_paper/figures/Fig_2_mean_mod_AE.pdf", height = 7, width = 12)
#Plot split tsne
mean_mod

VlnPlots of avg. module exp. by stage and seurat cluster

colored by module

# reorder seurat clusters
for (i in seq(my.ses)) {
  my.ses[[i]]$seurat_clusters <- factor(
  my.ses[[i]]$seurat_clusters,
  levels = levels(my.ses[[i]]$seurat_clusters)[as.integer(str_extract(ord_levels[[i]], "\\d{1,2}$"))]
  )

}

vplots <- list()

for (i in seq(my.ses)) {
  
  mods <- colnames(my.ses[[i]][[]])[grep("^AE",colnames(my.ses[[i]][[]]))]
  
  vplots[[i]] <- VlnPlot(
        my.ses[[i]],
        features = mods[module_order],
        group.by = "seurat_clusters",
        stack = TRUE, flip = TRUE,
        cols = substring(mods, 3)[module_order]) +
    theme(legend.position = "none") +
    geom_hline(yintercept = 0, lty = "dashed")
  
}

vplots[[1]]

vplots[[2]]

vplots[[3]]

pdf("~/spinal_cord_paper/figures/Fig_2_AE_by_cluster_modcol.pdf", height = 20, width = 10)
vplots[[1]]
vplots[[2]]
vplots[[3]]

colored by cell type

clust_col <- read.csv("~/spinal_cord_paper/annotations/broad_cluster_marker_colors.csv")

vplots_id <- list()

for (i in seq(my.ses)) {
    
  mods <- colnames(my.ses[[i]][[]])[grep("^AE",colnames(my.ses[[i]][[]]))]
  
  vplots_id[[i]] <- VlnPlot(
    my.ses[[i]],
    features = mods[module_order],
    group.by = "seurat_clusters",
    stack = TRUE, flip = TRUE,
    fill.by = "ident",
    cols = col_table[[i]]$color[as.integer(str_extract(ord_levels[[i]], "\\d{1,2}$"))]) +
    theme(legend.position = "none") +
    geom_hline(yintercept = 0, lty = "dashed")
}

vplots_id[[1]]

vplots_id[[2]]

vplots_id[[3]]

pdf("~/spinal_cord_paper/figures/Fig_2_AE_by_cluster_clucol.pdf", height = 20, width = 10)
vplots_id[[1]]
vplots_id[[2]]
vplots_id[[3]]

MN modules

For the figures we specifically select the two MN modules and plot them as Vln plots.

tmp <- avg.mod.eigengenes 
  
identical(rownames(tmp), colnames(my.sec))
## [1] TRUE
# add meta data to the int seurat object
my.sec <- AddMetaData(my.sec, tmp)
my.sec <- AddMetaData(my.sec, my.metam[c("fine", "sample_celltype")])

custom_order <- c(paste(names(ord_levels)[1], ord_levels[[1]], sep = '_'),
                  paste(names(ord_levels)[2], ord_levels[[2]], sep = '_'),
                  paste(names(ord_levels)[3], ord_levels[[3]], sep = '_'))

my.sec$sample_celltype <- factor(
  my.sec$sample_celltype,
  levels = custom_order
  )

vln_ind <- VlnPlot(my.sec,
                   features = c("AEdarkred", "AElightgreen", "AEdarkgreen"),
                   group.by = "sample_celltype",
                   stack = TRUE,
                   flip = TRUE,
                   cols = c("darkred", "lightgreen", "darkgreen"),pt.size = 1
                  ) +
    NoLegend()

vln_ind

pdf("~/spinal_cord_paper/figures/Fig_2_AE_selected_mod.pdf", height = 22, width = 20)
vln_ind
VlnPlot(
    my.sec,
    features = mods[module_order],
    group.by = "sample_celltype",
    stack = TRUE, flip = TRUE,
    cols = substring(mods, 3)[module_order]) +
    theme(legend.position = "none") +
    geom_hline(yintercept = 0, lty = "dashed")

pdf("~/spinal_cord_paper/figures/Fig_2_AE_by_cluster_integrated_data.pdf", height = 20, width = 30)
VlnPlot(
    my.sec,
    features = mods[module_order],
    group.by = "sample_celltype",
    stack = TRUE, flip = TRUE,
    cols = substring(mods, 3)[module_order]) +
    theme(legend.position = "none") +
    geom_hline(yintercept = 0, lty = "dashed")
# Date and time of Rendering
Sys.time()
## [1] "2024-08-30 14:02:33 CEST"
sessionInfo()
## R version 4.1.0 (2021-05-18)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: CentOS Linux 7 (Core)
## 
## Matrix products: default
## BLAS/LAPACK: /scicore/soft/apps/OpenBLAS/0.3.1-GCC-7.3.0-2.30/lib/libopenblas_sandybridgep-r0.3.1.so
## 
## locale:
## [1] en_US.UTF-8
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] gridExtra_2.3         pheatmap_1.0.12       cowplot_1.1.1        
##  [4] forcats_0.5.1         dplyr_1.0.10          purrr_0.3.4          
##  [7] readr_1.4.0           tibble_3.1.8          tidyverse_1.3.1      
## [10] patchwork_1.1.1       stringr_1.4.0         ggplot2_3.3.3        
## [13] tidyr_1.1.3           WGCNA_1.70-3          fastcluster_1.2.3    
## [16] dynamicTreeCut_1.63-1 SeuratObject_4.0.2    Seurat_4.0.5         
## 
## loaded via a namespace (and not attached):
##   [1] utf8_1.2.1             reticulate_1.22        tidyselect_1.2.0      
##   [4] RSQLite_2.2.7          AnnotationDbi_1.54.0   htmlwidgets_1.5.3     
##   [7] grid_4.1.0             Rtsne_0.15             munsell_0.5.0         
##  [10] codetools_0.2-18       ica_1.0-2              preprocessCore_1.54.0 
##  [13] future_1.30.0          miniUI_0.1.1.1         withr_2.4.2           
##  [16] colorspace_2.0-1       Biobase_2.52.0         highr_0.9             
##  [19] knitr_1.41             rstudioapi_0.13        stats4_4.1.0          
##  [22] ROCR_1.0-11            tensor_1.5             listenv_0.8.0         
##  [25] labeling_0.4.2         GenomeInfoDbData_1.2.6 polyclip_1.10-0       
##  [28] farver_2.1.0           bit64_4.0.5            parallelly_1.33.0     
##  [31] vctrs_0.5.1            generics_0.1.3         xfun_0.34             
##  [34] R6_2.5.0               doParallel_1.0.16      GenomeInfoDb_1.28.0   
##  [37] bitops_1.0-7           spatstat.utils_3.0-1   cachem_1.0.5          
##  [40] assertthat_0.2.1       promises_1.2.0.1       scales_1.1.1          
##  [43] nnet_7.3-16            gtable_0.3.0           globals_0.16.2        
##  [46] goftest_1.2-2          rlang_1.0.6            splines_4.1.0         
##  [49] lazyeval_0.2.2         impute_1.66.0          spatstat.geom_3.0-3   
##  [52] broom_0.7.6            checkmate_2.0.0        yaml_2.2.1            
##  [55] reshape2_1.4.4         abind_1.4-5            modelr_0.1.8          
##  [58] crosstalk_1.1.1        backports_1.2.1        httpuv_1.6.1          
##  [61] Hmisc_4.5-0            tools_4.1.0            ellipsis_0.3.2        
##  [64] spatstat.core_2.1-2    jquerylib_0.1.4        RColorBrewer_1.1-2    
##  [67] BiocGenerics_0.38.0    ggridges_0.5.3         Rcpp_1.0.7            
##  [70] plyr_1.8.6             base64enc_0.1-3        zlibbioc_1.38.0       
##  [73] RCurl_1.98-1.3         rpart_4.1-15           deldir_1.0-6          
##  [76] pbapply_1.4-3          S4Vectors_0.30.0       zoo_1.8-9             
##  [79] haven_2.4.1            ggrepel_0.9.1          cluster_2.1.2         
##  [82] fs_1.5.0               magrittr_2.0.1         data.table_1.14.0     
##  [85] scattermore_0.7        lmtest_0.9-38          reprex_2.0.1          
##  [88] RANN_2.6.1             fitdistrplus_1.1-6     matrixStats_0.58.0    
##  [91] hms_1.1.0              mime_0.10              evaluate_0.20         
##  [94] xtable_1.8-4           jpeg_0.1-8.1           readxl_1.3.1          
##  [97] IRanges_2.26.0         compiler_4.1.0         KernSmooth_2.23-20    
## [100] crayon_1.4.1           htmltools_0.5.1.1      mgcv_1.8-35           
## [103] later_1.2.0            Formula_1.2-4          lubridate_1.7.10      
## [106] DBI_1.1.1              dbplyr_2.1.1           MASS_7.3-54           
## [109] Matrix_1.3-3           cli_3.4.1              parallel_4.1.0        
## [112] igraph_1.2.6           pkgconfig_2.0.3        foreign_0.8-81        
## [115] sp_1.4-5               plotly_4.10.0          spatstat.sparse_3.0-0 
## [118] xml2_1.3.2             foreach_1.5.1          bslib_0.2.5.1         
## [121] XVector_0.32.0         rvest_1.0.2            digest_0.6.27         
## [124] sctransform_0.3.3      RcppAnnoy_0.0.19       spatstat.data_3.0-0   
## [127] Biostrings_2.60.0      rmarkdown_2.17         cellranger_1.1.0      
## [130] leiden_0.3.9           htmlTable_2.2.1        uwot_0.1.10           
## [133] shiny_1.6.0            lifecycle_1.0.3        nlme_3.1-152          
## [136] jsonlite_1.7.2         viridisLite_0.4.0      fansi_0.5.0           
## [139] pillar_1.8.1           lattice_0.20-44        KEGGREST_1.32.0       
## [142] fastmap_1.1.0          httr_1.4.2             survival_3.2-11       
## [145] GO.db_3.13.0           glue_1.6.2             png_0.1-7             
## [148] iterators_1.0.13       bit_4.0.4              stringi_1.6.2         
## [151] sass_0.4.0             blob_1.2.1             latticeExtra_0.6-29   
## [154] memoise_2.0.0          irlba_2.3.3            future.apply_1.7.0